package com.zyl.blog.common.exception;

import com.zyl.blog.common.enums.ResultCode;
import lombok.Getter;

import java.io.Serial;

/**
 * 自定义业务异常，用于封装业务逻辑错误和系统错误。
 *
 * @version v1.0
 * @ProjectName: Personal_Blog
 * @Package: com.zyl.common.exception
 * @ClassName: EccpException
 * @Description: 通过错误码(code)和消息(message)标识异常类型，支持携带原始异常链。
 * @Author FinalFantasy
 * @Date 2025/2/14-13:46
 */
@Getter
public class BlogException extends RuntimeException {

    @Serial
    private static final long serialVersionUID = 1L;

    /** 错误码（通常与 {@link ResultCode} 枚举中的预定义错误码一致） */
    private final int code;

    /**
     * 构造一个默认系统错误的异常（默认错误码为 SYSTEM_ERROR）。
     *
     * @param message 错误描述（例如："用户信息查询失败"）
     */
    public BlogException(String message) {
        this(ResultCode.INTERNAL_ERROR.getCode(), message);
    }

    /**
     * 构造一个默认系统错误的异常，并携带原始异常链。
     *
     * @param message 错误描述
     * @param cause   原始异常（例如：数据库异常、IO异常等）
     */
    public BlogException(String message, Throwable cause) {
        this(ResultCode.INTERNAL_ERROR.getCode(), message, cause);
    }

    /**
     * 构造一个自定义错误码和消息的异常。
     *
     * @param code    错误码（例如：400、500）
     * @param message 错误描述
     */
    public BlogException(int code, String message) {
        super(message);
        this.code = code;
    }

    /**
     * 构造一个自定义错误码和消息的异常，并携带原始异常链。
     *
     * @param code    错误码
     * @param message 错误描述
     * @param cause   原始异常
     */
    public BlogException(int code, String message, Throwable cause) {
        super(message, cause);
        this.code = code;
    }

    /**
     * 直接通过 {@link ResultCode} 枚举构造异常。
     *
     * @param resultCode 预定义的错误码枚举（例如：SYSTEM_ERROR、PARAM_INVALID）
     */
    public BlogException(ResultCode resultCode) {
        super(resultCode.getMessage());
        this.code = resultCode.getCode();
    }

    /**
     * 通过 {@link ResultCode} 枚举构造异常，并携带原始异常链。
     *
     * @param resultCode 预定义的错误码枚举
     * @param cause      原始异常
     */
    public BlogException(ResultCode resultCode, Throwable cause) {
        super(resultCode.getMessage(), cause);
        this.code = resultCode.getCode();
    }
}